package com.hp.netty;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author hp
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    Map<Integer, ChannelHandlerContext> numberMap = new ConcurrentHashMap<>();
    Map<String, Integer> ctxMap = new ConcurrentHashMap<>();

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        log.info("handlerAdded方法被调用，新增客户端：{}, {}", ctx.channel().id().asLongText(), ctx.channel().id().asShortText());
        int randomNum = getRandomNum();
        numberMap.put(randomNum, ctx);
        ctxMap.put(ctx.channel().id().asLongText(), randomNum);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        log.info("服务器收到消息：{}", msg.text());

        try {
            JSONObject jsonObject = JSON.parseObject(msg.text());
            String type = jsonObject.getString("type");

            if ("requestUserId".equals(type)) {
                // 处理请求用户ID的请求
                Integer userId = ctxMap.get(ctx.channel().id().asLongText());
                if (userId != null) {
                    String response = JSON.toJSONString(Map.of("type", "connect", "userId", userId));
                    ctx.channel().writeAndFlush(new TextWebSocketFrame(response));
                } else {
                    log.warn("无法找到用户ID");
                }
            } else if ("message".equals(type)) {
                Integer sender = jsonObject.getIntValue("sender");
                Integer receiver = jsonObject.getIntValue("receiver");
                String message = jsonObject.getString("message");

                // 构建转发消息
                String forwardMessage = String.format("来自 %s 的消息: %s", sender, message);
                TextWebSocketFrame textWebSocketFrame = new TextWebSocketFrame(JSON.toJSONString(Map.of("type", "message", "message", forwardMessage)));

                // 获取接收者的 ChannelHandlerContext
                ChannelHandlerContext receiverCtx = numberMap.get(receiver);
                if (receiverCtx != null) {
                    receiverCtx.channel().writeAndFlush(textWebSocketFrame);
                } else {
                    log.warn("接收者 {} 不在线", receiver);
                }
            }
        } catch (JSONException e) {
            log.error("解析消息失败", e);
            ctx.close();
        }
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        String channelId = ctx.channel().id().asLongText();
        log.info("handlerRemoved 被调用，连接关闭：{}", channelId);
        // 从临时映射中移除
        Integer number = ctxMap.remove(channelId);
        numberMap.remove(number);
        // 从用户映射中移除
        log.info("用户 {} 离线", number);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("异常发生 {}", cause.getMessage());
        // 发生异常时关闭连接
        ctx.close();
    }

    private int getRandomNum() {
        Random rand = new Random();
        // 生成一个四位的随机数
        return rand.nextInt(9000) + 1000;
    }
}
